#include <iostream>
#include <string>
#include <type_traits>
#include <functional>
#include "function_traits.hpp" // 需要包含我们的function_traits头文件

// 打印类型的模板函数
template <typename T>
void PrintType()
{
    std::cout << "Type: " << typeid(T).name() << std::endl;
}

// 类型转换函数声明
float (*castfunc)(std::string, int);

// 自由函数定义
float free_function(const std::string &a, int b)
{
    return static_cast<float>(a.size()) / b;
}

// 结构体 AA 定义
struct AA
{
    // volatile 函数成员
    int f(int a, int b) volatile
    {
        return a + b;
    }

    // const 运算符重载
    int operator()(int) const
    {
        return 0;
    }
};

// 测试函数特征
void TestFunctionTraits()
{
    std::cout << "=== Advanced Function Traits Tests ===" << std::endl;

    // 创建一个 lambda 函数
    std::function<int(double)> f = [](double a)
    { return a; };

    // 1. 测试 std::function
    std::cout << "\n1. std::function traits:" << std::endl;
    PrintType<function_traits<std::function<int(double)>>::function_type>();
    PrintType<function_traits<std::function<int(double)>>::args<0>::type>();

    // 2. 测试 lambda/std::function
    std::cout << "\n2. Lambda/std::function traits:" << std::endl;
    PrintType<function_traits<decltype(f)>::function_type>();
    std::cout << "Arity: " << function_traits<decltype(f)>::arity << std::endl;

    // 单独的lambda表达式
    // 分割线
    std::cout << "\n单独的lambda表达式" << std::endl;
    auto lambda = [](int a, int b)
    { return a + b; };
    PrintType<function_traits<decltype(lambda)>::function_type>();
    PrintType<function_traits<decltype(lambda)>::return_type>();
    PrintType<function_traits<decltype(lambda)>::args<0>::type>();
    PrintType<function_traits<decltype(lambda)>::args<1>::type>();
    // PrintType<function_traits<decltype(lambda)>::arity>();
    PrintType<function_traits<decltype(lambda)>::stl_function_type>();
    PrintType<function_traits<decltype(lambda)>::pointer>();
    // 分割线

    // 3. 测试自由函数
    std::cout << "\n3. Free function traits:" << std::endl;
    PrintType<function_traits<decltype(free_function)>::function_type>();
    PrintType<function_traits<decltype(free_function)>::return_type>();

    // 4. 测试函数指针
    std::cout << "\n4. Function pointer traits:" << std::endl;
    PrintType<function_traits<decltype(castfunc)>::function_type>();

    // 5. 测试成员函数
    std::cout << "\n5. Member function traits:" << std::endl;
    using MemberFuncType = decltype(&AA::f);
    PrintType<MemberFuncType>();
    PrintType<function_traits<MemberFuncType>::function_type>();

    // 6. 测试函数对象
    std::cout << "\n6. Function object traits:" << std::endl;
    PrintType<function_traits<AA>::function_type>();

    // 类型检查
    static_assert(std::is_same<function_traits<decltype(f)>::return_type, int>::value,
                  "Return type should be int");
    static_assert(function_traits<decltype(f)>::arity == 1,
                  "Should have 1 argument");
}

int main()
{
    TestFunctionTraits();
    return 0;
}